package com.pig4cloud.pig.village.contract.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.village.api.dto.LandContractDTO;
import com.pig4cloud.pig.village.api.dto.LandContractTotalDTO;
import com.pig4cloud.pig.village.api.entity.LandContract;
import com.pig4cloud.pig.village.api.entity.Team;
import com.pig4cloud.pig.village.api.entity.Villager;
import com.pig4cloud.pig.village.contract.mapper.LandContractMapper;
import com.pig4cloud.pig.village.contract.service.ILandContractService;
import com.pig4cloud.pig.village.team.service.ITeamService;
import com.pig4cloud.pig.village.villager.service.IVillagerService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author limbray.li
 * @date 2021/6/19
 */
@Service
@RequiredArgsConstructor
public class LandContractServiceImpl extends ServiceImpl<LandContractMapper, LandContract> implements ILandContractService {
	@Resource
	private IVillagerService villagerService;
	@Resource
	private ITeamService teamService;
	@Resource
	private LandContractMapper landContractMapper;

	@Override
	public IPage<LandContractDTO> selectForPage(Page page, Long teamId, Integer year, Long villagerId) {
		year = year == null ? DateUtil.thisYear() : year;
		LambdaQueryWrapper<LandContract> query = Wrappers.lambdaQuery();
		query.eq(teamId != null, LandContract::getTeamId, teamId);
		query.eq(LandContract::getYear, year);
		query.eq(villagerId != null, LandContract::getVillagerId, villagerId);
		IPage<LandContract> pages = super.page(page, query);
		Map<Long, Villager> villagerMap = getVillagerMap(pages.getRecords());
		Map<Long, String> teamNameMap = getTeamNameMap(pages.getRecords());
		IPage<LandContractDTO> result = pages.convert(e -> landConvert(e, villagerMap, teamNameMap));
		return result;
	}

	private Map<Long, Villager> getVillagerMap(List<LandContract> list) {
		List<Long> villagerIds = list.stream().map(LandContract::getVillagerId).collect(Collectors.toList());
		if (CollectionUtils.isEmpty(villagerIds)) {
			return null;
		}
		List<Villager> villagers = villagerService.listByIds(villagerIds);
		Map<Long, Villager> villagerMap = villagers.stream().collect(Collectors.toMap(Villager::getId, Function.identity()));
		return villagerMap;
	}

	private Map<Long, String> getTeamNameMap(List<LandContract> list) {
		List<Long> teamIds = list.stream().map(LandContract::getTeamId).collect(Collectors.toList());
		if (CollectionUtils.isEmpty(teamIds)) {
			return null;
		}
		List<Team> teams = teamService.listByIds(teamIds);
		Map<Long, String> teamNameMap = teams.stream().collect(Collectors.toMap(Team::getId, Team::getTeamName));
		return teamNameMap;
	}

	private LandContractDTO landConvert(LandContract e, Map<Long, Villager> villagerMap, Map<Long, String> teamNameMap) {
		LandContractDTO dto = new LandContractDTO();
		BeanUtil.copyProperties(e, dto);
		Villager v = null;
		String teamName = "";
		if (villagerMap != null) {
			villagerMap.get(e.getVillagerId());
		}
		if (teamNameMap != null) {
			teamName = teamNameMap.get(e.getTeamId());
		}
		if (v != null) {
			dto.setVillagerName(v.getName());
			dto.setCreditCard(v.getBankCard());
			dto.setIdentityCard(v.getIdentityCard());
			dto.setPhone(v.getPhone());
		}
		dto.setTeamName(teamName);
		return dto;
	}


	@Override
	public LandContractDTO getDtoById(Long id) {
		LandContract landContract = super.getById(id);
		Villager v = villagerService.getById(landContract.getVillagerId());
		Team team = teamService.getById(landContract.getTeamId());
		LandContractDTO dto = new LandContractDTO();
		BeanUtil.copyProperties(v, dto);
		if (v != null) {
			dto.setVillagerName(v.getName());
			dto.setCreditCard(v.getBankCard());
			dto.setIdentityCard(v.getIdentityCard());
			dto.setPhone(v.getPhone());
		}
		dto.setTeamName(team.getTeamName());
		return dto;
	}

	@Override
	public List<LandContractTotalDTO> teamTotal(Long teamId, Integer year) {
		List<LandContractTotalDTO> result = new ArrayList<>();
		year = year == null ? DateUtil.thisYear() : year;
		if (teamId != null) {
			LandContractTotalDTO dto = landContractMapper.oneTotal(year, teamId);
			Team team = teamService.getById(teamId);
			dto.setType("team");
			dto.setName(team.getTeamName());
			result.add(dto);
		} else {
			result = landContractMapper.groupTotal(year);
			result.forEach(e -> e.setType("team"));
		}
		return result;
	}

	@Override
	public LandContractTotalDTO villageTotal(Integer year) {
		year = year == null ? DateUtil.thisYear() : year;
		LandContractTotalDTO dto = landContractMapper.oneTotal(year, null);
		dto.setType("village");
		dto.setName("all");
		return dto;
	}
}
